#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
dubbo 服务
"""

__author__ = 'Lei Chen'
__all__ = ['config', 'dubbo_invoke']

import urllib.parse
import telnetlib
import demjson
from kazoo.client import KazooClient
from dubbo import config
import logging

dubboConfig = config.DubboConfigParser().config()


def __dubbo_server(server):
    zk_host = dubboConfig.host
    zk_timeout = int(dubboConfig.timeout)
    zkc = KazooClient(hosts=zk_host, timeout=zk_timeout)
    try:
        zkc.start()
        providers = zkc.get_children(dubboConfig.node.format(server))
        if len(providers) != 0:
            for provider in providers:
                url = urllib.parse.unquote(provider)
                url_result = urllib.parse.urlparse(url)
                netloc = url_result.netloc
                netlocs = netloc.split(':')
                return netlocs[0], netlocs[1]
    except Exception as err:
        logging.error(err)
        return None, None


def dubbo_invoke(server, method, params):
    try:
        host, port = __dubbo_server(server)
        result = Dubbo(host, port).invoke(server, method, params)
        return True, result
    except Exception as err:
        return False, err


class Dubbo(telnetlib.Telnet):
    prompt = 'dubbo>'
    coding = 'utf-8'

    def __init__(self, host=None, port=0):
        super().__init__(host, port, timeout=1)
        self.write(b'\n')

    def command(self, flag, str_=""):
        data = self.read_until(flag.encode())
        self.write(str_.encode() + b"\n")
        return data

    def invoke(self, service_name, method_name, arg):
        if arg:
            command_str = "invoke {0}.{1}({2})".format(
                service_name, method_name, demjson.encode(arg))
        else:
            command_str = "invoke {0}.{1}()".format(
                service_name, method_name)

        self.command(Dubbo.prompt, command_str)
        data = self.command(Dubbo.prompt, "")
        data = demjson.decode(data.decode(Dubbo.coding,
                                          errors='ignore').split('\n')[0].strip())
        return data

    def ls(self):
        self.command(Dubbo.prompt, 'ls')
        data = self.command(Dubbo.prompt, "")
        data = data.decode(Dubbo.coding,
                           errors='ignore').split()
        return data


def main():
    pass


if __name__ == '__main__':
    main()
